package com.zmn.oms.admin.controller.common;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.zmn.base.product.common.consts.BaseProductConsts;
import com.zmn.base.product.common.dto.categ.CategProductGroupDRO;
import com.zmn.base.product.common.query.categ.CategProductGroupQuery;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.engstock.common.model.dro.StockItemDRO;
import com.zmn.engstock.common.model.dro.stock.StockUsedOrderDetailDRO;
import com.zmn.oms.admin.controller.OmsBaseController;
import com.zmn.oms.business.interfaces.grid.GridGroupDistributeBService;
import com.zmn.oms.business.interfaces.orderstock.OrderStockBService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderDistributeConsts;
import com.zmn.oms.common.constant.OrderGateTypeConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.dro.conf.distribute.DistributeArgsDRO;
import com.zmn.oms.common.dro.conf.distribute.DistributeConfigDRO;
import com.zmn.oms.common.dro.conf.distribute.PlatDirectlyDistributeArgsDRO;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.bo.product.ProductBO;
import com.zmn.oms.model.bo.work.schedule.GridGroupScheduleBO;
import com.zmn.oms.model.dto.orderstock.ReleaseStockDTO;
import com.zmn.oms.model.dto.orderstock.StockWhiteDTO;
import com.zmn.oms.model.dto.work.schedule.WorkOrderScheduleQuery;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.orderstock.UsedOrderStockDetailVo;
import com.zmn.oms.model.vo.work.schedule.DefaultDutyTimeVO;
import com.zmn.oms.model.vo.work.schedule.OrderScheduleVO;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkScheduleBService;
import com.zmn.oms.zmn.business.interfaces.work.customwork.ZsDistributeWorkBService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 类描述：排期
 *
 * @author liuying
 * @date 2018/11/21 15:36
 */
@Controller
@RequestMapping("/schedule")
public class ScheduleController extends OmsBaseController {

    @Resource
    private ZsOrderWorkScheduleBService zsOrderWorkScheduleBService;

    @Autowired
    private OrderStockBService orderStockBService;
    @Autowired
    private GridGroupDistributeBService gridGroupDistributeBService;
    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    private ZsDistributeWorkBService zsDistributeWorkBService;


    /**
     * 获取排期
     *
     * @param query
     * @return
     */
    @RequestMapping(value = "/time")
    @ResponseBody
    public ResultDTO time(WorkOrderScheduleQuery query) {
        logger.info("获取预约日期可用时间段查询参数：{}", JSON.toJSONString(query));
        Long workId = query.getWorkId();
        this.buildWorkOrderScheduleQuery(query);

        // 非新单，不接入库存和网格组派单
        if (Objects.equals(OrderConsts.ORDER_TYPE_NEW, query.getType())) {
            OrderWork orderWork = null;
            if (Objects.nonNull(workId)) {
                orderWork = orderWorkService.findOrderWorkByKey(workId, workId);
            }

            // 七天内有可服务工程师走网格组逻辑 七天内无工程师 走兜底逻辑
            if (query.getIsAvailableWeek()) {
                // 新增订单 或 修改订单但无工程师的情况走网格组的预约时间逻辑
                if (NumberUtil.isNullOrZero(workId) || Objects.isNull(orderWork) || NumberUtil.isNullOrZero(orderWork.getMasterId())) {
                    OrderScheduleVO orderScheduleVO = zsOrderWorkScheduleBService.getScheduleTimesNew(query);
                    logger.info("新单-无工程师走网格组逻辑={}", orderScheduleVO);
                    if (Objects.equals(OrderConsts.ORDER_SCHE_NONE_TIMES_96, orderScheduleVO.getTimes())) {
                        orderScheduleVO.setDefaultActiveIndex(null);
                        orderScheduleVO.setDefaultActiveTime(null);
                    }
                    return ResultDTO.success(orderScheduleVO);
                }
            }

            // 修改订单且存在工程师的情况 走动态库存的预约时间逻辑
            if (Objects.nonNull(orderWork) && NumberUtil.isNotNullOrZero(orderWork.getMasterId())) {
                OrderScheduleVO orderScheduleVO = zsOrderWorkScheduleBService.getScheduleTimes(query.getScheDate(), null);
                logger.info("新单-有工程师走动态库存逻辑={}", orderScheduleVO);
                // 过滤不可选的时间
                String times = zsOrderWorkScheduleBService.processScheduleTimes(workId, query.getPlatWork(), OrderGateTypeConsts.GATE_PLAT_BACKSTAGE, orderScheduleVO.getTimes());
                orderScheduleVO.setTimes(times);

                try {
                    // 工单信息
                    StockWhiteDTO stockWhiteDTO = StockWhiteDTO.builder()
                            .masterId(orderWork.getMasterId())
                            .workCityId(orderWork.getCityId())
                            .build();
                    if (!orderStockBService.isWhiteByAllConditions(stockWhiteDTO)) {
                        return ResultDTO.success(orderScheduleVO);
                    }

                    // 是否占用库存
                    boolean isExit = orderStockBService.checkExitOrder(orderWork.getWorkId(), orderWork.getMasterId());
                    if (!isExit) {
                        return ResultDTO.success(orderScheduleVO);
                    }

                    // 可用库存过滤
                    List<StockItemDRO> stockItemDROS = orderStockBService.getStockByEngineerIdAndProductGroupId(query.getScheDate(), orderWork.getMasterId(), query.getProductGroupCode(), query.getProductNum(), workId);
                    times = processStockDutyTimeInfo(times, stockItemDROS);
                    orderScheduleVO.setTimes(times);

                    // 设置默认选择时间
                    int curDay = Integer.parseInt(DateUtil.toString(DateUtil.getNow(), DateUtil.FORMAT_DATE2));
                    int scheDay = Integer.parseInt(DateUtil.toString(DateUtil.parse(query.getScheDate(), DateUtil.FORMAT_DATE), DateUtil.FORMAT_DATE2));
                    if (curDay == scheDay) {
                        char[] timeChars = times.toCharArray();
                        for (int i = 0; i < timeChars.length; i++) {
                            Character tmp = timeChars[i];
                            // 如果是启用状态，判断是否包含在库存中，如果不包含，不能启用
                            if (tmp.equals('1')) {
                                orderScheduleVO.setDefaultActiveIndex(i);
                                break;
                            }
                        }
                    }

                    if (query.getIsGrid()) {
                        // 获取指定工程师使用的订单库存详情
                        List<StockUsedOrderDetailDRO> list = orderStockBService.getStockUserOrderDetailByQuery(orderWork.getMasterId(), query.getScheDate(), query.getScheDate());
                        if (CollectionUtil.isNotNullOrEmpty(list)) {
                            List<UsedOrderStockDetailVo> usedOrderStockDetailVoList = list.stream().map(stockUsedOrderDetailDRO -> {
                                UsedOrderStockDetailVo usedOrderStockDetailVo = BeanMapper.map(stockUsedOrderDetailDRO, UsedOrderStockDetailVo.class);
                                // 计算排期索引
                                usedOrderStockDetailVo.setStartIndex(calculateTimeIndex(usedOrderStockDetailVo.getStartDate()));
                                usedOrderStockDetailVo.setEndIndex(calculateTimeIndex(usedOrderStockDetailVo.getEndDate()));
                                // 计算是否超时
                                Date nowTime = DateUtil.getNow();
                                if (Objects.equals(usedOrderStockDetailVo.getDate(), DateUtil.toString(nowTime, DateUtil.FORMAT_DATE))
                                        && usedOrderStockDetailVo.getStartIndex() < calculateTimeIndex(DateUtil.toString(nowTime, "HH:mm"))) {
                                    usedOrderStockDetailVo.setTimeOut(GlobalConsts.YES);
                                }

                                return usedOrderStockDetailVo;
                            }).collect(Collectors.toList());
                            orderScheduleVO.setUsedOrderStockDetailVoList(usedOrderStockDetailVoList);
                        }
                    }
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                    logger.error("库存异常-返回服务可用");
                }
                if (Objects.equals(OrderConsts.ORDER_SCHE_NONE_TIMES_96, times)) {
                    orderScheduleVO.setDefaultActiveIndex(null);
                    orderScheduleVO.setDefaultActiveTime(null);
                }
                return ResultDTO.success(orderScheduleVO);
            }
        }
        // 兜底走原始获取预约时间段逻辑
        OrderScheduleVO orderScheduleVO = zsOrderWorkScheduleBService.getScheduleTimes(query.getScheDate(), null);
        logger.info("兜底走原始获取预约时间段逻辑={}", orderScheduleVO);
        // 过滤不可选的时间
        String times = zsOrderWorkScheduleBService.processScheduleTimes(workId, query.getPlatWork(), OrderGateTypeConsts.GATE_PLAT_BACKSTAGE, orderScheduleVO.getTimes());
        orderScheduleVO.setTimes(times);
        if (Objects.equals(OrderConsts.ORDER_SCHE_NONE_TIMES_96, times)) {
            orderScheduleVO.setDefaultActiveIndex(null);
            orderScheduleVO.setDefaultActiveTime(null);
        }
        return ResultDTO.success(orderScheduleVO);
    }

    /**
     * 获取后台排期
     *
     * @param query
     * @return
     */
    @RequestMapping(value = "/back/time")
    @ResponseBody
    public ResultDTO backTime(WorkOrderScheduleQuery query) {
        logger.info("获取预约日期可用时间段查询参数：{}", JSON.toJSONString(query));
        Long workId = query.getWorkId();
        this.buildWorkOrderScheduleQuery(query);

        // 兜底走原始获取预约时间段逻辑
        OrderScheduleVO orderScheduleVO = zsOrderWorkScheduleBService.getScheduleTimes(query.getScheDate(), 7);
        logger.info("兜底走原始获取预约时间段逻辑={}", orderScheduleVO);
        // 过滤不可选的时间
        String times = zsOrderWorkScheduleBService.processScheduleTimes(workId, query.getPlatWork(), OrderGateTypeConsts.GATE_PLAT_BACKSTAGE, orderScheduleVO.getTimes());
        orderScheduleVO.setTimes(times);
        if (Objects.equals(OrderConsts.ORDER_SCHE_NONE_TIMES_96, times)) {
            orderScheduleVO.setDefaultActiveIndex(null);
            orderScheduleVO.setDefaultActiveTime(null);
        }
        return ResultDTO.success(orderScheduleVO);
    }

    /**
     * 获取自动派单时间
     *
     * @param query
     * @return
     */
    @RequestMapping(value = "/auto/distribute/time", method = RequestMethod.GET)
    @ResponseBody
    public ResultDTO getAutoDistributeTime(WorkOrderScheduleQuery query) {
        this.buildWorkOrderScheduleQuery(query);
        // 获取派单配置
        OrderWork orderWork = new OrderWork();
        orderWork.setPlatWork(query.getPlatWork());
        orderWork.setPlat(query.getPlat());
        orderWork.setBizType(query.getBizType());
        orderWork.setCityId(query.getCityId());
        orderWork.setServProductGroupId(query.getProductGroupId());
        DistributeConfigDRO distributeConfigDRO = zsDistributeWorkBService.getDistributeConfig(orderWork);

        String autoDistributeTIme = "";
        // 平台直派
        if (Objects.equals(distributeConfigDRO.getDistributeWay(), OrderDistributeConsts.DISTRIBUTE_WAY_PLAT)) {
            PlatDirectlyDistributeArgsDRO platDirectlyDistributeArgsDRO = distributeConfigDRO.getPlatDirectlyDistributeArgsDRO();
            autoDistributeTIme += platDirectlyDistributeArgsDRO.getAutoTimeStart() + "-" + platDirectlyDistributeArgsDRO.getAutoTimeEnd();
        } else {
            DistributeArgsDRO distributeArgsDRO = distributeConfigDRO.getDistributeArgsDRO();
            autoDistributeTIme += distributeArgsDRO.getAutoTimeStart() + "-" + distributeArgsDRO.getAutoTimeEnd();
        }
        return ResultDTO.success(autoDistributeTIme);
    }

    /**
     * 日期
     *
     * @return
     */
    @RequestMapping(value = "/date", method = RequestMethod.GET)
    @ResponseBody
    public ResultDTO date() {
        Map<String, Object> map = Maps.newHashMap();
        map.put("nowTime", DateUtil.getNowFormatted(DateUtil.FORMAT_DEFAULT));
        map.put("dateList", zsOrderWorkScheduleBService.getScheduleDayList());
        return ResultDTO.success(map);
    }

    /**
     * 获取默认预约时间
     *
     * @param workOrderScheduleQuery 工单排期查询对象
     * @return
     * @modifier huangchao 2022/04/01 取消动态库存逻辑 新增网格组派单逻辑
     */
    @RequestMapping(value = "/defaulttime")
    @ResponseBody
    public ResultDTO defaultDutyTime(WorkOrderScheduleQuery workOrderScheduleQuery) {
        logger.info("获取默认预约时间查询参数：{}", JSON.toJSONString(workOrderScheduleQuery));
        this.buildWorkOrderScheduleQuery(workOrderScheduleQuery);
        DefaultDutyTimeVO defaultDutyTimeVO = new DefaultDutyTimeVO();
        if (workOrderScheduleQuery.getIsGrid() && Objects.equals(OrderConsts.ORDER_TYPE_NEW, workOrderScheduleQuery.getType())) {
            if (Objects.nonNull(workOrderScheduleQuery.getLatitude())
                    && Objects.nonNull(workOrderScheduleQuery.getLatitude())) {
                try {
                    GridGroupScheduleBO gridGroupScheduleBO = gridGroupDistributeBService.getGridGroupFirstAvailableDates(workOrderScheduleQuery);
                    if (!gridGroupScheduleBO.getHasEngineerFlag() && Objects.nonNull(gridGroupScheduleBO.getCanServiceDate())) {
                        String girdGroupDistributeShowStr = String.format("当天无工程师可服务,%s有工程师可服务", DateUtil.toString(gridGroupScheduleBO.getCanServiceDate(), "M月d日"));
                        defaultDutyTimeVO.setGirdGroupDistributeShowStr(girdGroupDistributeShowStr);
                        return ResultDTO.success(defaultDutyTimeVO);
                    } else if (!gridGroupScheduleBO.getHasEngineerFlag() && Objects.isNull(gridGroupScheduleBO.getCanServiceDate())) {
                        if (!Objects.equals(gridGroupScheduleBO.getGridGroupType(), 3)) {
                            defaultDutyTimeVO.setIsAvailableWeek(Boolean.FALSE);
                        }
                        defaultDutyTimeVO.setGirdGroupDistributeShowStr("当前时间最近7天无可服务的工程师");
                        return ResultDTO.success(defaultDutyTimeVO);
                    }
                } catch (Exception e) {
                    logger.error("获取网格组派单失败-走获取默认预约时间：{}", e);
                }
            }
        }

        String defaultDutyTime;
        if (StringUtil.isNotBlank(workOrderScheduleQuery.getDutyTime())) {
            defaultDutyTime = workOrderScheduleQuery.getDutyTime();
        } else {
            defaultDutyTime = zsOrderWorkScheduleBService.getDefaultHalfPointDutyTime(workOrderScheduleQuery.getPlat(), OrderGateTypeConsts.GATE_PLAT_BACKSTAGE);
        }

        if (StringUtils.isBlank(defaultDutyTime)) {
            return ResultDTO.success(defaultDutyTimeVO);
        }

        String nowFormatted = DateUtil.getNowFormatted(DateUtil.FORMAT_DATE);
        String defaultDutyTimeFormatted = DateUtil.dateFormatToString(defaultDutyTime, DateUtil.FORMAT_DATETIME, DateUtil.FORMAT_DATE);

        defaultDutyTimeVO.setShowDutyTime(defaultDutyTime);
        defaultDutyTimeVO.setDutyTime(defaultDutyTime);
        defaultDutyTimeVO.setIsToday(Objects.equals(nowFormatted, defaultDutyTimeFormatted));
        return ResultDTO.success(defaultDutyTimeVO);
    }

    /**
     * 运营平台获取默认预约时间
     *
     * @param workOrderScheduleQuery 工单排期查询对象
     */
    @RequestMapping(value = "/back/defaultTime")
    @ResponseBody
    public ResultDTO backDefaultDutyTime(WorkOrderScheduleQuery workOrderScheduleQuery) {
        logger.info("获取默认预约时间查询参数：{}", JSON.toJSONString(workOrderScheduleQuery));
        this.buildWorkOrderScheduleQuery(workOrderScheduleQuery);
        DefaultDutyTimeVO defaultDutyTimeVO = new DefaultDutyTimeVO();

        String defaultDutyTime;
        if (StringUtil.isNotBlank(workOrderScheduleQuery.getDutyTime())) {
            defaultDutyTime = workOrderScheduleQuery.getDutyTime();
        } else {
            defaultDutyTime = zsOrderWorkScheduleBService.getBackStageDefaultDutyTime(workOrderScheduleQuery);
        }

        if (StringUtils.isBlank(defaultDutyTime)) {
            return ResultDTO.success(defaultDutyTimeVO);
        }

        String nowFormatted = DateUtil.getNowFormatted(DateUtil.FORMAT_DATE);
        String defaultDutyTimeFormatted = DateUtil.dateFormatToString(defaultDutyTime, DateUtil.FORMAT_DATETIME, DateUtil.FORMAT_DATE);

        defaultDutyTimeVO.setShowDutyTime(defaultDutyTime);
        defaultDutyTimeVO.setDutyTime(defaultDutyTime);
        defaultDutyTimeVO.setIsToday(Objects.equals(nowFormatted, defaultDutyTimeFormatted));
        return ResultDTO.success(defaultDutyTimeVO);
    }

    @RequestMapping(value = "/release/stock")
    @ResponseBody
    public ResultDTO releaseStock(Long orderId, Long workId, Integer masterId, Integer cityId) {
        ReleaseStockDTO releaseStockDTO = ReleaseStockDTO.builder()
                .masterId(masterId)
                .workId(workId)
                .orderId(orderId)
                .cityId(cityId)
                .build();
        try {
            orderStockBService.releaseStock(releaseStockDTO);
        } catch (OmsBaseException e) {
            return ResultDTO.fail(e.getMessage());
        }

        return ResultDTO.success();
    }

    /**
     * 获取工单上工程师的排期工单详情
     *
     * @param workId
     * @param cityId
     * @return
     */
    @GetMapping(value = "/getStockUsedOrderDetail")
    @ResponseBody
    public ResultDTO getStockUsedOrderDetail(@RequestParam Long workId, @RequestParam Integer cityId) {
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(workId, workId);
        // 平台直派调用 前台限制
        Integer workStatus = orderWork.getStatus();
        if (Objects.equals(OrderStatusConsts.WORK_STATUS_DISTRIBUTE, workStatus)
                || Objects.equals(OrderStatusConsts.WORK_STATUS_TAKE, workStatus)
                || Objects.equals(OrderStatusConsts.WORK_STATUS_VISIT, workStatus)) {
            // 校验是否走动态库存
            StockWhiteDTO stockWhiteDTO = StockWhiteDTO.builder()
                    .masterId(orderWork.getMasterId())
                    .workCityId(orderWork.getCityId())
                    .build();
            if (!orderStockBService.isWhiteByAllConditions(stockWhiteDTO)) {
                return ResultDTO.success();
            }

            // 获取指定工程师使用的订单库存详情
            List<StockUsedOrderDetailDRO> list = orderStockBService.getStockUserOrderDetailByEngineerId(orderWork.getMasterId());
            if (CollectionUtil.isNotNullOrEmpty(list)) {
                List<UsedOrderStockDetailVo> usedOrderStockDetailVoList = list.stream().map(stockUsedOrderDetailDRO -> {
                    UsedOrderStockDetailVo usedOrderStockDetailVo = BeanMapper.map(stockUsedOrderDetailDRO, UsedOrderStockDetailVo.class);
                    // 计算排期索引
                    usedOrderStockDetailVo.setStartIndex(calculateTimeIndex(usedOrderStockDetailVo.getStartDate()));
                    usedOrderStockDetailVo.setEndIndex(calculateTimeIndex(usedOrderStockDetailVo.getEndDate()));
                    return usedOrderStockDetailVo;
                }).collect(Collectors.toList());
                return ResultDTO.success(usedOrderStockDetailVoList);
            }
        }
        return ResultDTO.success();
    }

    /**
     * 校验两个工单是否可交换库存
     *
     * @param workId
     * @param exchangeWorkId
     * @return
     */
    @GetMapping(value = "/checkServTimeCanChang")
    @ResponseBody
    public ResultDTO checkServTimeCanChang(@RequestParam Long workId, @RequestParam Long exchangeWorkId) {
        if (Objects.equals(workId, exchangeWorkId)) {
            return ResultDTO.success(Boolean.FALSE);
        }
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(workId, workId);
        Boolean checkServTimeCanChang = orderStockBService.checkServTimeCanChang(orderWork.getMasterId(), workId, exchangeWorkId);
        return ResultDTO.success(checkServTimeCanChang);
    }

    private String processStockDutyTimeInfo(String times, List<StockItemDRO> stockItemList) {
        if (CollectionUtil.isNullOrEmpty(stockItemList)) {
            return OrderConsts.ORDER_SCHE_NONE_TIMES_96;
        }

        Set<Integer> canUsedIndexSet = Sets.newHashSet();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm");
        for (StockItemDRO stockItem : stockItemList) {
            for (String time : stockItem.getTimeList()) {
                String[] split = time.split(" - ");
                LocalTime startTime = LocalTime.parse(split[0], dateTimeFormatter);
                canUsedIndexSet.add(startTime.getHour() * 4 + startTime.getMinute() / 15);
                LocalTime endTime = LocalTime.parse(split[1], dateTimeFormatter);
                canUsedIndexSet.add(endTime.getHour() * 4 + endTime.getMinute() / 15);
            }
        }

        char[] timeChars = times.toCharArray();
        for (int i = 0; i < timeChars.length; i++) {
            Character tmp = timeChars[i];
            // 如果是启用状态，判断是否包含在库存中，如果不包含，不能启用
            if (tmp.equals('1') && !canUsedIndexSet.contains(i)) {
                timeChars[i] = '0';
            }
        }

        return new String(timeChars);
    }


    public void buildWorkOrderScheduleQuery(WorkOrderScheduleQuery query) {
        ProductBO showProductBO = new ProductBO();
        ProductBO productBO = new ProductBO();
        if (NumberUtil.isNotNullOrZero(query.getShowProductId())) {
            showProductBO = this.getShowProductByProductId(query.getShowProductId());
        }
        if (NumberUtil.isNotNullOrZero(query.getProductId())) {
            productBO = this.getProductByProductId(query.getProductId());

            // 设置前台产品
            showProductBO = this.getShowProductByProductId(query.getProductId());
        }
        if (NumberUtil.isNotNullOrZero(productBO.getCategId())) {
            // 后台产品分组
            logger.info("servAssCategoryListRemoteService#getProductGroupByCategId 查询产品分组 入参：servCateg={}, categTwoId={}", query.getServCategId(), productBO.getCategId());
            CategProductGroupQuery categProductGroupQuery = new CategProductGroupQuery();
            categProductGroupQuery.setBizType(query.getBizType());
            categProductGroupQuery.setServCategId(query.getServCategId());
            categProductGroupQuery.setCategId(productBO.getCategId());
            categProductGroupQuery.setShowType(BaseProductConsts.ERP_SHOW_TYPE);
            query.setCategId(productBO.getCategId());
            ResponseDTO<CategProductGroupDRO> categoryProductGroupDROResponseDTO = categServProductListRemoteService.getBasisProductGroupByQuery(categProductGroupQuery);
            logger.info("servAssCategoryListRemoteService#getProductGroupByCategId 查询产品分组 出参：【{}】", categoryProductGroupDROResponseDTO);
            CategProductGroupDRO categorySimpleProductGroupDRO = categoryProductGroupDROResponseDTO.getData();
            if (categorySimpleProductGroupDRO != null) {
                query.setProductGroupId(categorySimpleProductGroupDRO.getGroupId());
                query.setProductGroupCode(categorySimpleProductGroupDRO.getGroupCode());
            }
        } else if (NumberUtil.isNotNullOrZero(showProductBO.getCategId())) {
            // 前台产品分组
            logger.info("servAssCategoryListRemoteService#getProductGroupByShowCategId 查询产品分组 入参：servCateg={}, categTwoId={}", query.getServCategId(), showProductBO.getCategId());
            CategProductGroupQuery categProductGroupQuery = new CategProductGroupQuery();
            categProductGroupQuery.setBizType(query.getBizType());
            categProductGroupQuery.setServCategId(query.getServCategId());
            categProductGroupQuery.setCategId(showProductBO.getCategId());
            categProductGroupQuery.setShowType(BaseProductConsts.EC_SHOW_TYPE);
            query.setCategId(productBO.getCategId());
            ResponseDTO<CategProductGroupDRO> responseDTO = categServProductListRemoteService.getBasisProductGroupByQuery(categProductGroupQuery);
            logger.info("servAssCategoryListRemoteService#getProductGroupByShowCategId 查询产品分组 出参：【{}】", responseDTO);
            CategProductGroupDRO categorySimpleProductGroupDRO = responseDTO.getData();
            if (categorySimpleProductGroupDRO != null) {
                query.setProductGroupId(categorySimpleProductGroupDRO.getGroupId());
                query.setProductGroupCode(categorySimpleProductGroupDRO.getGroupCode());

            }
        }
    }

    /**
     * 计算时间值索引
     */
    private Integer calculateTimeIndex(String time) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm");
        LocalTime startTime = LocalTime.parse(time, dateTimeFormatter);
        return startTime.getHour() * 4 + startTime.getMinute() / 15;
    }
}